package cn.edu.pku.ss.situationperceiver;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import cn.edu.pku.ss.situationperceiver.ContextData.ContextType;

public class SensorManager {
/**
 * Module: SensorManager
 * Responsibilities:
 * 1) Store the available sensors on this device.
 * 2) Provide a query method for other modules to check sensor capability.
 * 3) Generate context truth values as response to other local modules context request.
 */
	private List<Sensor> sensors;
	private HashMap<ContextType, ContextTruthValue> truthValueGenerator;
	
	private void readSensors()
	{
		try {
    		SAXParserFactory factory = SAXParserFactory.newInstance();
			SAXParser parser = factory.newSAXParser();
			XMLReader reader = parser.getXMLReader();
			SensorHandler handler = new SensorHandler();
			reader.setContentHandler(handler);
			InputSource is = new InputSource(this.getClass().getResourceAsStream("sensorConfiguration.xml"));
			reader.parse(is);
			sensors = handler.getSensors();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private void readTruthValueGenerator()
	{
		try {
    		SAXParserFactory factory = SAXParserFactory.newInstance();
			SAXParser parser = factory.newSAXParser();
			XMLReader reader = parser.getXMLReader();
			ContextHandler handler = new ContextHandler();
			reader.setContentHandler(handler);
			InputSource is = new InputSource(this.getClass().getResourceAsStream("contextGenerator.xml"));
			reader.parse(is);
			truthValueGenerator = handler.getTruthValueMapper();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public SensorManager()
	{
		readTruthValueGenerator();
		readSensors();
	}
	
	public boolean checkAvailability(ContextType contextType)
	{
		Iterator<Sensor> itr = sensors.iterator();
		while(itr.hasNext())
		{
			Sensor sensor = itr.next();
			if(sensor.contextType == contextType)
				return true;
		}
		return false;
	}
	
	public ContextData querySensor(ContextType contextType)
	{
		String truthValue;
		ContextTruthValue contextTruthValue = truthValueGenerator.get(contextType);
		Random random = new Random();
		
		if(contextTruthValue.isDiscrete)
		{
			int i = random.nextInt(2);
			if(i == 0)
				truthValue = contextTruthValue.lValue;
			else
				truthValue = contextTruthValue.rValue;
		}
		else
		{
			int lNumber = Integer.parseInt(contextTruthValue.lValue);
			int rNumber = Integer.parseInt(contextTruthValue.rValue);
			int i = random.nextInt(rNumber - lNumber + 1);
			truthValue = lNumber + i + "";
		}
		
		Date genDate = new Date();
		Calendar c = Calendar.getInstance();
		c.setTime(genDate);
		c.add(Calendar.SECOND, random.nextInt(100));
		Date expireDate = c.getTime();
		
		return new ContextData(contextType, truthValue, genDate, expireDate);
	}
}
